//
//  Primer_Properties_DemoVC.swift
//  APSwift
//
//  Created by jianbo.pei on 2022/5/19.
//

import UIKit

class Primer_Properties_DemoVC: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        test1()
        test2()
        test3()
        test4()
        test5()
    }


}

struct PPoint {
    var x = 0.0, y = 0.0
}
struct PSize {
    var width = 0.0, height = 0.0
}
struct PRect {
    var origin = PPoint()
    var size = PSize()
//    var center: PPoint {
//        get {
//            let centerX = origin.x + (size.width / 2)
//            let centerY = origin.y + (size.height / 2)
//            return PPoint(x: centerX, y: centerY)
//        }
//        set(newCenter) {
//            origin.x = newCenter.x - (size.width / 2)
//            origin.y = newCenter.y - (size.height / 2)
//        }
//    }
    
    var center: PPoint {
        get {
            /// 简化`Getter`声明
            /// 如果整个`getter`是单一表达式，`getter`会隐式地返回这个表达式结果。
            PPoint(x: origin.x + (size.width / 2), y: origin.y + (size.height / 2))
        }
        set {
            /// 简化`Setter`声明
            /// 如果计算属性的`setter`没有定义表示新值的参数名，则可以使用默认名称`newValue`。
            origin.x = newValue.x - (size.width / 2)
            origin.y = newValue.y - (size.height / 2)
        }
    }
}

extension Primer_Properties_DemoVC {
    private func test1() {
        var square = PRect(origin: PPoint(x: 0.0, y: 0.0),
            size: PSize(width: 10.0, height: 10.0))
        square.center = PPoint(x: 15.0, y: 15.0)
        print("square.origin is now at (\(square.origin.x), \(square.origin.y))")
        // 打印“square.origin is now at (10.0, 10.0)”
    }
    
    private func test2() {
        let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)
        print("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)")
        // 打印“the volume of fourByFiveByTwo is 40.0”
    }
    
}

//!!!: 只读属性
/// 参考链接：https://swiftgg.gitbook.io/swift/swift-jiao-cheng/10_properties#readonly-computed-properties
struct Cuboid {
    var width = 0.0, height = 0.0, depth = 0.0
    var volume: Double {
        width * height * depth
    }
}


struct PPerson {
    var age: Int
    var name: String
}

extension Primer_Properties_DemoVC {
    func test3() {
        let p1 = PPerson(age: 18, name: "你好")
        debugPrint("p1's name is \(p1.name), age is \(p1.age)")
    }
}

//!!!: 延迟存储属性
struct PLocation {
    var x = 0
    var y = 0
    lazy var z = 0
}

extension Primer_Properties_DemoVC {
    func test4() {
        /// Cannot use mutating getter on immutable value: 'loc' is a 'let' constant
//        let loc = PLocation()
        var loc = PLocation()
        debugPrint("loc.z is \(loc.z)")
    }
}


struct PCircle {
    /// 存储属性
    var radius: Double
    /// 计算属性
    var diamter: Double {
        set {
            radius = newValue / 2
        }
        get {
            radius * 2
        }
    }
}

extension Primer_Properties_DemoVC {
    private func test5() {
        print("size: \(MemoryLayout<PCircle>.size)")
        print("stride: \(MemoryLayout<PCircle>.stride)")
        print("alignment: \(MemoryLayout<PCircle>.alignment)")
        /**
         size: 8
         stride: 8
         alignment: 8
         */
    }
    
    /**
     结论：
     - 只有radius这个存储属性会存储在实力对象，占用堆空间，
     - 而diameter这个计算属性相当于方法，不会占用堆空间，
     - 所以类占用的内存空间为8字节，只是radius这个存储属性的8字节
     */
}
